type t 'a;
(** The type of setHash of type ['a]. *)
value empty : unit -> t 'a;
(** [HashSet.empty()] creates an empty set of zero size. *)
value singleton : 'a -> t 'a;
(** [HashSet.singleton k] create a new set with one element [k] *)
value create : int -> t 'a;
(** [HashSet.create n k] creates a new, empty set with
   initial size [n]. For best results, [n] should be on the
   order of the expected number of elements that will be in
   the table.  The table grows as needed, so [n] is just an
   initial guess.
   [k] is a key of type ['a] which must be provided to
   initialize the set; it is for internal use; it cannot
   be accessed.  *)
value length : t 'a -> int;
(** [HashSet.length h] returns the number of elements
   in the set. *)
value is_empty : t 'a -> bool;
value capacity : t 'a -> int;
(** [HashSet.capacity] is the size of the set, i.e. the number 
    of elements which the set can contain before resizing when 
    adding a new element. *)
value clear : t 'a -> unit;
(** Empty a set. *)
value copy : t 'a -> t 'a;
(** [HashSet.copy h] returns a copy of h *)
value mem : t 'a -> 'a -> bool;
(** [HashSet.mem h x] checks if [x] is a member of [h]. *)
value iter : ('a -> unit) -> t 'a -> unit;
(** [HashSet.iter f h] applies [f] to all elements of
    the set. The order in which the elements are passed 
    to [f] is unspecified. *)
value enum : t 'a -> Enum.t 'a;
(** [HashSet.enum h] Convert HashSet h to Enum.t *)
value add_unsafe : t 'a -> 'a -> unit;
(** [HashSet.add_unsafe h x] adds [x] to the set [h],
    without resizing the set. If the number of
    elements is much more than the size of the set,
    performance is poor.  *)
value copy_resize : t 'a -> int -> t 'a;
(** [HashSet.copy_resize h n] return a new set
    with the same elements as [h] and with size [n] *)
value add : t 'a -> 'a -> unit;
(** [HashSet.add h x] adds [x] to the set [h],
    resizing the set when the number of elements is
    equal or more than the size of the set. *)
value remove : t 'a -> 'a -> unit;
(** [HashSet.remove h x] removes the element [x] from
    the set [h]. Often the element is still in the set,
    but it is not accessible. Furthermore, the size of
    the set does not change. *)
value choose : t 'a -> option 'a;
value pop : t 'a -> option 'a;
value of_list : list 'a -> t 'a;
value to_list : t 'a -> list 'a;
value to_array: t 'a -> array 'a;
value bucket_lengths : t 'a -> array int;
value fold : ('a -> 'b -> 'b) -> t 'a -> 'b -> 'b;
(** [HashSet.fold f h a] computes [(f xN ... (f x2 (f x1 a))...)],
    where [x1 ... xN] are the elements in [s].
    The order in which the elements are passed to [f] is unspecified. *)
value for_all : ('a -> bool) -> t 'a -> bool;
(** [HashSet.for_all p h] checks if all elements of the set [h]
    satisfy the predicate [p]. *)
value exists : ('a -> bool) -> t 'a -> bool;
(** [HashSet.exists p h] checks if at least one element of
    the set satisfies the predicate [p]. *)
value keys : t 'a -> array 'a;
(** [HashSet.keys h] returns an array with the elements of the set
    in unspecified order. *)
value equal : t 'a -> t 'a -> bool;
(** [HashSet.equal h1 h2]  tests whether the sets [h1] and [h2] are
   equal, that is, contain equal elements. *)
value update : t 'a -> t 'a -> unit;
value diff_update : t 'a -> t 'a -> unit;
value symmetric_diff_update : t 'a -> t 'a -> unit;
value inter_update : t 'a -> t 'a -> unit;
value union : t 'a -> t 'a -> t 'a;
value diff : t 'a -> t 'a -> t 'a;
value symmetric_diff : t 'a -> t 'a -> t 'a;
value inter : t 'a -> t 'a -> t 'a;
(** Functorial interface *)
module type HashedType =
  sig
    type t;
    (** The type of the elements. *)
    value compare : t -> t -> int;
    (** The comparison function used to compare elements. *)
    value hash : t -> int;
  end;
(** A hashing function on elements. It must be such that if two elements 
      are equal according to [compare], then they have identical hash
      values as computed by [hash]. *)
(* The input signature of the functor {!Hashset.Make}. *)
module type S =
  sig
    type elt;
    type t;
    value empty : unit -> t;
    value create : int -> t;
    value length : t -> int;
    value is_empty : t -> bool;
    value capacity : t -> int;
    value mem : t -> elt -> bool;
    value clear : t -> unit;
    value copy : t -> t;
    value iter_v : (elt -> unit) -> t -> unit;
    value iter : (elt -> unit) -> t -> unit;
    value add_unsafe : t -> elt -> unit;
    value copy_resize : t -> int -> t;
    value resize : t -> elt -> unit;
    value add : t -> elt -> unit;
    value remove : t -> elt -> unit;
    value choose : t -> option elt;
    value pop : t -> option elt;
    value of_list : list elt -> t;
    value to_list : t -> list elt;
    value enum : t -> Enum.t elt;
    value bucket_lengths : t -> array int;
    value fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a;
    value for_all : (elt -> bool) -> t -> bool;
    value exists : (elt -> bool) -> t -> bool;
    value keys : t -> array elt;
    value equal : t -> t -> bool;
    value update : t -> t -> unit;
    value diff_update : t -> t -> unit;
    value symmetric_diff_update : t -> t -> unit;
    value inter_update : t -> t -> unit;
    value union : t -> t -> t;
    value diff : t -> t -> t;
    value symmetric_diff : t -> t -> t;
    value inter : t -> t -> t;
  end;
module Make (H : HashedType) : S with type elt = H.t;

